#ifndef READXML_H
#define READXML_H

#include <iostream>
#include <map>
#include <vector>

#include "tinyxml.h"
#include "tinystr.h"


class RwXml
{
public:
    RwXml();
    RwXml(const char *xmlpath);
    ~RwXml();    

    TiXmlDocument *getDoc() const;
    void setDoc(TiXmlDocument *Doc);

    void saveDom();
    void saveDom(const char* path);

    //获得根元素
    TiXmlElement* getRootElement();

    //查询一个指定xml节点，通过
    //对应参数：1.节点名称 2.属性名称 3.属性值 4.读取后的xml
    TiXmlNode* selectSingleNode(std::string nodeName,std::string nodeAttrName,std::string nodeAttrValue);
    TiXmlNode* selectSingleNode(std::string nodeName);
    TiXmlNode* selectSingleNode(std::string nodeName,TiXmlNode *parentNode);

    //通过节点名称返回节点vector
    //对应参数：1.读取后xml 2.节点名称
    std::vector<TiXmlNode*> getNodeVec(const char* nodeName);
    //1.读取后xml 2.父节点的名字
    std::vector<TiXmlNode*> getNodeVec(const char* nodeName,TiXmlNode *parentNode);
    //在特定节点下查找所需节点
    std::vector<TiXmlNode*> getSelectNodeVec(const char* nodeName,TiXmlNode* selectNode);

    //增加一个节点,通过
    //对应参数：1.父节点名称（通过SelectSingleNode或getNodeVec查找） 2.节点名称 3.读取后xml 4.属性map<属性名称,属性值>
    bool addSingleNode(TiXmlNode *tNode, const char* nodeName, std::map<const char*, const char*> attrmap);
    bool addSingleNode(TiXmlNode *tNode,const char* nodeName,std::map<std::string, std::string> attrmap);

    //添加结点并返回添加的结点
    TiXmlNode* addSingleNodeAndReturn(TiXmlNode *tNode, const char* nodeName, std::map<const char*, const char*> attrmap);
    TiXmlNode* addSingleNodeAndReturn(TiXmlNode *tNode, std::string strNodeName, std::map<std::string, std::string> attrmap);

    //添加一个无属性节点
    //对应参数：1.父节点名称（通过SelectSingleNode或getNodeVec查找） 2.节点名称 3.读取后xml
    bool addNoAttrNode(TiXmlNode *tNode,const char* nodeName);

    //在父节点下添加子节点
    //对应参数：1.父节点2.子节点
    void addNoAttrNode(TiXmlNode* &tNode,TiXmlElement* &cNode);
    TiXmlNode* addNoAttrNodeAndReturn(TiXmlNode *tNode,const char* nodeName);

    //遍历子节点，并放入vector中
    //对应参数: 1.遍历节点 2.节点名称 3.节点vector
    void insertNodeVec(TiXmlNode * pNode, const char* nodeName,std::vector<TiXmlNode*> &nodeVec);

    //修改元素属性值
    //对应参数：1.需要修改的节点 2.属性名 3.属性值
    TiXmlNode* changeNodeAttr(TiXmlNode *node, std::string AttrName, std::string AttrValue);

    //删除一个节点,通过
    //对应参数：1.删除节点 （通过SelectSingleNode查找）2.读取后xml
    bool delSingleNode(TiXmlNode *tNode);

private:
    //读取xml文件,通过
    TiXmlDocument* readDoc(const char* xmlpath);
    //根据父节点循环遍历查找子节点,通过
    //辅助SelectSingleNode使用，不需要单独调用    
    TiXmlNode* selectChildNode(TiXmlNode* pNode,std::string nodeName);
    TiXmlNode* selectChildNode(TiXmlNode* pNode,std::string nodeName,std::string nodeAttrName,std::string nodeAttrValue);
    TiXmlDocument *m_pDoc;
};

#endif // READXML_H
